package csc.fresher.view;

import java.io.IOException;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.PostConstruct;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import csc.fresher.commons.BankingConstant;
import csc.fresher.dao.InternetAccountDAO;
import csc.fresher.entity.AccountState;
import csc.fresher.entity.AccountTransactionState;
import csc.fresher.entity.Currency;
import csc.fresher.entity.Customer;
import csc.fresher.entity.CustomerAccountOverall;
import csc.fresher.entity.DepositAccount;
import csc.fresher.entity.InternetAccount;
import csc.fresher.entity.SavingAccount;
import csc.fresher.entity.SystemUser;
import csc.fresher.service.AccountService;
import csc.fresher.service.CurrencyService;
import csc.fresher.service.SystemUserService;
import csc.fresher.commons.EncryptMD5;

@Component
@Scope("session")
public class AccountManageBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private final String email_pattern = "^[_a-z0-9-]+(\\.[_a-z0-9-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.[a-z]{2,4})$";
	private final String phone_pattern = "^\\s*\\d+\\s*$";
	private final String idCardNumber_pattern = "^\\s*\\d+\\s*$";
	private final String balance_pattern = "^\\s*\\d+\\s*$"; // "^-?\\d*\\.\\d+$"
																// + "|" +
																// "^-?\\d+$";

	private String firstName;
	private String lastName;
	private String midName;
	private String idCardNumber;
	private String address;
	private String address2;
	private String phone;
	private String phone2;
	private String email;
	private String email2;
	private String accountType;
	private String accountBalance;
	private static Pattern pattern;
	private static Matcher matcher;
	private static String emailStatus;
	private static String phoneStatus;
	private static String emailStatus2;
	private static String phoneStatus2;
	private static String idCardNumberStatus;
	private static String balanceStatus;
	private static String username;
	private static String password;
	private static String checkUniqueIDCardNumber;

	private String currency;
	private String showCurrency;

	@Autowired
	AccountService accountService;

	@Autowired
	private InternetAccountDAO internetAccountDao;
	
	@Autowired
	private SystemLoginManageBean systemLoginManageBean;
	
	@Autowired
	private SystemUserService systemUserService;
	
	@Autowired
	private CurrencyService currencyServices;
	
	
	public void onLoad() {
		
		firstName = "";
		lastName = "";
		midName = "";
		idCardNumber = "";
		address = "";
		address2 = "";
		phone = "";
		phone2 = "";
		email = "";
		email2 = "";
		accountBalance = "";
	
		SystemUser systemUser;
		
		if(systemLoginManageBean.getSystemUser() == null) {
			try {
				FacesContext.getCurrentInstance().getExternalContext().redirect("/csc_final/templates3/Logon.jsf");
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			systemUser = systemLoginManageBean.getSystemUser();
			List<Long> listrole = systemUserService.getRoleByUserName(systemUser.getUserName());			
			boolean result = checkRole(listrole);
			if(result == false) {
				try {
					FacesContext.getCurrentInstance().getExternalContext().redirect("AccountManagement.xhtml");
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	@PostConstruct
	public void init() {
	
		this.showCurrency= "hide";
		this.accountType = "deposit";
		emailStatus = "";
		phoneStatus = "";
		phoneStatus2 = "";
		emailStatus2 = "";
		idCardNumberStatus="";
		balanceStatus = "";
	}

	public boolean checkRole(List<Long> listRole) {
		
		for(int i = 0; i < listRole.size(); i++) {
			if (4 == listRole.get(i) || 3 == listRole.get(i)){
				return true;
			}
		}		
		return false;
	}

	
	
	public String submit() {
		try {
			if (checkAllInput() == false) {
				emailStatus = "";
				phoneStatus = "";
				phoneStatus2 = "";
				emailStatus2 = "";
				idCardNumberStatus="";
				balanceStatus = "";
				return "AddAccount";
				
			} else {
				Customer customer = new Customer();
				customer.setFirstName(firstName);
				customer.setMidName(midName);
				customer.setLastName(lastName);
				customer.setIdCardNumber(Long.parseLong(idCardNumber));
				customer.setAddress(address);
				customer.setAddress2(address2);
				customer.setPhoneNumber(phone);
				customer.setPhoneNumber2(phone2);
				customer.setEmail(email);
				customer.setEmail2(email2);
				customer.setRemovable(false);
				customer.setCreatedBy((int)(systemLoginManageBean.getSystemUser().getSystemUserID()));
				customer.setApprovedBy(1);				
				customer.setCreatedDate(new Timestamp(System
						.currentTimeMillis()));
				customer.setLastUpdate(new Timestamp(System.currentTimeMillis()));
				long insertResult = accountService.createCustomer(customer);
				InternetAccount internetAccount = new InternetAccount();
				internetAccount.setCustomerID(insertResult);
				internetAccount.setUsername(username);
				internetAccount.setPassword(EncryptMD5.md5(password));
				internetAccount.setLock(false);
				internetAccountDao.createInternetAccount(internetAccount);
				if (insertResult == 0) {
					return "addAccountError";
				} else if ("deposit".equals(accountType)) {
					DepositAccount depositAccount = new DepositAccount();
					depositAccount.setAccountBalance(Double
							.parseDouble(accountBalance));
					depositAccount
							.setAccountType(BankingConstant.ACCOUNT_TYPE_DEPOSIT);
					depositAccount.setAccountState(AccountState.NEW);
					depositAccount.setRepeatable(false);
					depositAccount.setCreatedDate(new Timestamp(System
							.currentTimeMillis()));
					depositAccount.setCustomerID(insertResult);
					depositAccount
							.setAccountTransactionState(AccountTransactionState.NEW);
					long depositNewNumber = accountService.createDepositAccount(depositAccount);
					if(depositNewNumber > 0) {
						return "DepositAccountManagement";
					} else {
						return "Error";
					}
				} else if ("saving".equals(accountType)) {
					SavingAccount savingAccount = new SavingAccount();
					savingAccount.setAccountBalance(Double
							.parseDouble(accountBalance));
					savingAccount
							.setAccountType(BankingConstant.ACCOUNT_TYPE_DEPOSIT);
					savingAccount.setAccountState(AccountState.NEW);
					savingAccount.setRepeatable(false);
					savingAccount.setCreatedDate(new Timestamp(System
							.currentTimeMillis()));
					savingAccount.setCustomerID(insertResult);
					savingAccount
							.setAccountTransactionState(AccountTransactionState.NEW);
					if(currency.equals("usd")){
						savingAccount.setCurrencyID(1);
					}else if(currency.equals("vnd")){
						savingAccount.setCurrencyID(2);
					}
					
					long savingNewNumber = accountService.createSavingAccount(savingAccount);
					if(savingNewNumber > 0) {
						return "SavingAccountManagement";
					} else {
						return "Error";
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "Error";

	}
	
	public void showCurrency(ValueChangeEvent ex){
	
		if(ex.getNewValue().toString().equals("saving")){
			emailStatus = "";
			phoneStatus = "";
			phoneStatus2 = "";
			emailStatus2 = "";
			idCardNumberStatus="";
			balanceStatus = "";
			showCurrency = "show";
			
		}else if(ex.getNewValue().toString().equals("deposit")){
			emailStatus = "";
			phoneStatus = "";
			phoneStatus2 = "";
			emailStatus2 = "";
			idCardNumberStatus="";
			balanceStatus = "";
			showCurrency = "hide";
		}else{

			showCurrency = "hide";
		}

	}
	

	public String cancel() {
		return "AcountManagement";
	}

	public String getMidName() {
		return midName;
	}

	public void setMidName(String midName) {
		this.midName = midName;
	}

	public String getIdCardNumber() {
		return idCardNumber;
	}

	public void setIdCardNumber(String idCardNumber) {
		if (checkIdCardNumber(idCardNumber) && checkUniqueIDCardNumber(idCardNumber)) {
			idCardNumberStatus = "";
		} else {
			idCardNumberStatus = "<span style='color:red; margin-left:10px'><b> Invalid ID Card Number Or This ID have been existed!</b></span>";
		}
		this.idCardNumber = idCardNumber;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getAddress2() {
		return address2;
	}

	public void setAddress2(String address2) {
		this.address2 = address2;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		if (checkValidPhone(phone)) {
			phoneStatus = "";
		} else {
			phoneStatus = ("<span style='color:red; margin-left:10px'><b> Invalid Phone!</b></span>");
		}
		this.phone = phone;
	}

	public String getPhone2() {
		return phone2;
	}

	public void setPhone2(String phone2) {
		if (checkValidPhone(phone2)) {
			phoneStatus2 = "";
		} else {
			phoneStatus2 = ("<span style='color:red; margin-left:10px'><b> Invalid Phone 2!</b></span>");
		}

		this.phone2 = phone2;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		if (checkValidEmail(email)) {
			emailStatus = "";
		} else {
			emailStatus = "<span style='color:red; margin-left: 10px'><b> Invalid Email!</b></span>";
		}
		this.email = email;
	}

	public String getEmail2() {
		return email2;
	}

	public void setEmail2(String email2) {
		if (checkValidEmail(email2)) {
			emailStatus2 = "";
		} else {
			emailStatus2 = "<span style='color:red; margin-left:10px'><b> Invalid Email 2!</b></span>";
		}
		this.email2 = email2;
	}

	public String getAccountType() {
		return accountType;
	}

	public void setAccountType(String accountType) {
		this.accountType = accountType;
	}

	public static long getSerialversionuid() {
		return serialVersionUID;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getAccountBalance() {
		return accountBalance;
	}

	public void setAccountBalance(String accountBalance) {
		if (checkBalance(accountBalance)) {
			balanceStatus = "";
		} else {
			balanceStatus = "<span style='color:red; margin-left:10px'><b> Invalid Balance!</b></span>";
		}
		this.accountBalance = accountBalance;
	}

	public String getEmailStatus() {
		return emailStatus;
	}

	public void setEmailStatus(String emailStatus) {
		AccountManageBean.emailStatus = emailStatus;
	}

	public String getPhoneStatus() {
		return phoneStatus;
	}

	public void setPhoneStatus(String phoneStatus) {
		AccountManageBean.phoneStatus = phoneStatus;
	}

	public String getEmailStatus2() {
		return emailStatus2;
	}

	public void setEmailStatus2(String emailStatus2) {
		AccountManageBean.emailStatus2 = emailStatus2;
	}

	public String getPhoneStatus2() {
		return phoneStatus2;
	}

	public void setPhoneStatus2(String phoneStatus2) {
		AccountManageBean.phoneStatus2 = phoneStatus2;
	}

	public String getIdCardNumberStatus() {
		return idCardNumberStatus;
	}

	public void setIdCardNumberStatus(String idCardNumberStatus) {

		AccountManageBean.idCardNumberStatus = idCardNumberStatus;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		AccountManageBean.password = password;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		AccountManageBean.username = username;
	}

	public String getBalanceStatus() {
		return balanceStatus;
	}

	public void setBalanceStatus(String balanceStatus) {
		AccountManageBean.balanceStatus = balanceStatus;
	}

	public boolean checkValidEmail(String email) {

		pattern = Pattern.compile(email_pattern);
		matcher = pattern.matcher(email);
		return matcher.matches();

	}

	public boolean checkValidPhone(String phone) {
		pattern = Pattern.compile(phone_pattern);
		matcher = pattern.matcher(phone);
		return matcher.matches();
	}

	public boolean checkIdCardNumber(String idCardNumber) {

		pattern = Pattern.compile(idCardNumber_pattern);
		matcher = pattern.matcher(idCardNumber);
		return matcher.matches();

	}

	public boolean checkBalance(String balance) {

		pattern = Pattern.compile(balance_pattern);
		matcher = pattern.matcher(balance);
		return matcher.matches();
	}

	public boolean checkUniqueIDCardNumber(String idCardNumber) {
		List<Customer> listcustomer = new ArrayList<Customer>();
		listcustomer = accountService.findCustomerByIDCardNumber(Long
				.parseLong(idCardNumber));
		boolean result;
		if (listcustomer.size() < 1) {
			result = true;
		} else {
			result = false;
		}
		return result;
	}

	public boolean checkAllInput() {
		boolean result;
		if (firstName.equals("") || firstName == null) {
			result = false;
		} else if (lastName.equals("") || lastName == null) {
			result = false;
		} else if (String.valueOf(idCardNumber).equals("")) {
			result = false;
		} else if (address.equals("") || address == null) {
			result = false;
		} else if (phone.equals("") || phone == null) {
			result = false;
		} else if (email.equals("") || email == null) {
			result = false;
		} else if (!checkBalance(accountBalance)) {
			result = false;
		} else if (!checkIdCardNumber(idCardNumber)) {
			result = false;
		} else if (!checkUniqueIDCardNumber(idCardNumber)) {
			result = false;
		} else if (!checkValidEmail(email)) {
			result = false;
		} else if (!checkValidPhone(phone)) {
			result = false;
		} else {
			result = true;
		}
		return result;

	}

	public String getCheckUniqueIDCardNumber() {
		return checkUniqueIDCardNumber;
	}

	public void setCheckUniqueIDCardNumber(String checkUniqueIDCardNumber) {
		AccountManageBean.checkUniqueIDCardNumber = checkUniqueIDCardNumber;
	}



	public String getCurrency() {
		return currency;
	}

	public void setCurrency(String currency) {
		this.currency = currency;
	}


	public String getShowCurrency() {
		return showCurrency;
	}


	public void setShowCurrency(String showCurrency) {
		this.showCurrency = showCurrency;
		
	}



}
